let completionItems;
let editorTextarea;

function autoHeight() {
    $('#monaco-editor').height($(window).height() -$('#tips').height() - 40);
}

/**
 * 查找整个代码中的不符合规则的语法
 * @param value
 * @returns {undefined}
 * @constructor
 */
function GetErrors(value) {
    if(!(value && value.length>0)){
        return null;
    }
    let ret = [];
    // 查询一下有没有分号之类的
    let lines = value.split("\n");
    for (let i = 0; i <lines.length; i++) {
        let line = lines[i];
        if(line.trim()==''){
            continue;
        }
        let tmp = line.trim();
        let c = tmp.substring(tmp.length-1,tmp.length);
        if(c!=';'){
            if(new RegExp("[A-Za-z0-9:.)\\]]").test(c)){
                ret.push({
                    startLineNumber: i+1,
                    endLineNumber: i+1,
                    startColumn: line.length-1,
                    endColumn: line.length+1,
                    severity: monaco.MarkerSeverity.Error,
                    message: `可能这里需要的是半角分号`,
                })
            }
        }
    }
    return ret;
}

$(function () {
    // autoHeight();
    // $(window).resize(autoHeight);
    editorTextarea = monaco.editor.create(document.getElementById('monaco-editor'), {
        language: languageName,
        wordWrap: 'on',  //自行换行
        verticalHasArrows: true,
        horizontalHasArrows: true,
        contextmenu: true,
        dragAndDrop: true, //内容是否能拖动
        automaticLayout: true,
        fontSize: 13,
        autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
        autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
        autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
        folding: true, // 是否启用代码折叠
        scrollBeyondLastLine: true, // 设置编辑器是否可以滚动到最后一行之后
        renderLineHighlight: 'all', // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
        renderValidationDecorations:'on',
        formatOnPaste: true, // 粘贴时，是否自动格式化
        theme: languageTheme,
        minimap: {
            enabled: false // 小地图
        }
    });

    initCompletionItems();

    editorTextarea.getModel().onDidChangeContent(event => {
        let value = editorTextarea.getModel().getValue();
        let errors = GetErrors(value);
        monaco.editor.setModelMarkers(editorTextarea.getModel(), languageName, errors);
    });

    //run
    editorTextarea.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () {
        // runScript(false);
    });

    //保存
    editorTextarea.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S ,function () {
       // saveEditor('#editor-section')
    });

    //快捷键提示 ALT+/
    editorTextarea.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.US_SLASH, function () {
        editorTextarea.trigger('', 'editor.action.triggerSuggest', {});
    });

    //多行注释 CTRL+SHIFT+/
    editorTextarea.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.US_SLASH, function () {
        let selectRange = editorTextarea.getSelection();
        let prefixRange = new monaco.Range(selectRange.startLineNumber, selectRange.startColumn, selectRange.startLineNumber, selectRange.startColumn + 2);
        let prefix = editorTextarea.getModel().getValueInRange(prefixRange);
        let postfixRange = new monaco.Range(selectRange.endLineNumber, selectRange.endColumn - 2, selectRange.endLineNumber, selectRange.endColumn);
        let postfix = editorTextarea.getModel().getValueInRange(postfixRange);

        let prefixOp = {"range": prefixRange, "text": ""};
        let postfixOp = {"range": postfixRange, "text": ""};
        //取消注释
        if (prefix == '/*' && postfix == "*/") {
            editorTextarea.executeEdits('insert-code', [prefixOp])
            if (selectRange.startLineNumber == selectRange.endLineNumber) {
                postfixOp.range.startColumn = postfixOp.range.startColumn - 2;
                postfixOp.range.endColumn = postfixOp.range.endColumn - 2;
            }
            editorTextarea.executeEdits('insert-code', [postfixOp])
            return;
        }

        prefixRange = new monaco.Range(selectRange.startLineNumber, selectRange.startColumn, selectRange.startLineNumber, selectRange.startColumn);
        postfixRange = new monaco.Range(selectRange.endLineNumber, selectRange.endColumn, selectRange.endLineNumber, selectRange.endColumn);
        prefixOp = {"range": prefixRange, "text": "/*"};
        postfixOp = {"range": postfixRange, "text": "*/"};
        editorTextarea.executeEdits('insert-code', [prefixOp])
        if (selectRange.startLineNumber == selectRange.endLineNumber) {
            postfixOp.range.startColumn = postfixOp.range.startColumn + 2;
            postfixOp.range.endColumn = postfixOp.range.endColumn + 2;
        }
        editorTextarea.executeEdits('insert-code', [postfixOp])
    });

    //单行注释 CTRL+/
    editorTextarea.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.US_SLASH, function () {
        let selectRange = editorTextarea.getSelection();

        let isAdd = false;
        for (let i = selectRange.startLineNumber; i <= selectRange.endLineNumber; i++) {
            let lineNumber = i;
            let range = new monaco.Range(lineNumber, 0, lineNumber, 3);
            let prefix = editorTextarea.getModel().getValueInRange(range);
            if (prefix != "//") {
                isAdd = true;
                break;
            }
        }

        for (let i = selectRange.startLineNumber; i <= selectRange.endLineNumber; i++) {
            let lineNumber = i;
            let range = null;
            let text = null;
            if (isAdd) {
                range = new monaco.Range(lineNumber, 0, lineNumber, 0);
                text = "//";
            } else {
                range = new monaco.Range(lineNumber, 0, lineNumber, 3);
                text = "";
            }
            editorTextarea.executeEdits('insert-code', [{"range": range, "text": text}])
        }
    });
});

function initCompletionItems() {
    $.ajax({
        type: "post",
        url: '/system/schedule/ide/init',
        contentType: "application/json",
        // data: JSON.stringify({"api": api}),
        success: function (data) {
            completionItems = data;
        }
    });
}

function buildMethodsForClazz(clazz) {
    let cls = null;
    $.ajax({
        type: "post",
        url: '/system/schedule/ide/clazz',
        contentType: "application/json",
        async: false,//使用同步方式，方便返回值
        data: JSON.stringify({"clazz": clazz}),
        success: function (data) {
            if (data && data.classMethods) {
                $.each(data.classMethods, function (key, val) {
                    completionItems.clazzs[key] = val;
                    cls = key;
                });
            }
        }
    });
    return cls ? cls : clazz;
}

/**
 * 得到get或post过来的指定的参数
 * @param name
 * @returns {string}
 */
function getQueryString(name) {
    location.href.replace("#","");
    // 如果链接没有参数，或者链接中不存在我们要获取的参数，直接返回空
    if(location.href.indexOf("?")==-1 || location.href.indexOf(name+'=')==-1)     {
        return '';
    }
    // 获取链接中参数部分
    var queryString = location.href.substring(location.href.indexOf("?")+1);
    // 分离参数对 ?key=value&key2=value2
    var parameters = queryString.split("&");

    var pos, paraName, paraValue;
    for(var i=0; i<=parameters.length; i++) {
        // 获取等号位置
        pos = parameters[i].split('=');
        if(pos == -1) { continue; }
        // 获取name 和 value
        paraName = pos[0];
        paraValue = pos[1];
        // 如果查询的name等于当前name，就返回当前值，同时，将链接中的+号还原成空格
        if(paraName == name) {
            return decodeURIComponent(paraValue.replace(/\+/g, " "));
        }
    }
    return '';
}
